package com.cksys.achievement.config.login.qq;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cksys.achievement.entity.Role;
import com.cksys.achievement.entity.User;
import com.cksys.achievement.entity.UserRole;
import com.cksys.achievement.enums.EmailStatusEnum;
import com.cksys.achievement.enums.RegisterEnum;
import com.cksys.achievement.exception.MyUsernameNotFoundException;
import com.cksys.achievement.exception.NoBindingException;
import com.cksys.achievement.service.IRoleService;
import com.cksys.achievement.service.ISettingService;
import com.cksys.achievement.service.IUserRoleService;
import com.cksys.achievement.service.IUserService;
import com.cksys.achievement.service.impl.CustomUserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;

/**
 * @ClassName: QQBindingManager
 * @author: zyx
 * @E-mail: 1377631190@qq.com
 * @DATE: 2020/4/16 22:44
 */
@Component
public class QQBindingManager implements AuthenticationManager {

    @Autowired
    IUserService userService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    BCryptPasswordEncoder encoder;

    @Autowired
    ISettingService settingService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        Collection<GrantedAuthority> authorities = new HashSet<>();
        User user = (User) authentication.getPrincipal();
        String flag = (String) authentication.getCredentials();
        User userByUserName = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, user.getUsername()));
        if ("true".equalsIgnoreCase(flag)) {
            if (!userByUserName.getRegister().equals(RegisterEnum.REGISTER_YES)) {
                throw new NoBindingException(CustomUserDetailsServiceImpl.NOT_AUDITED);
            }
            if (!encoder.matches(user.getPassword(), userByUserName.getPassword())) {
                throw new NoBindingException("密码错误！");
            }
            if (!StringUtils.isEmpty(user.getEmail())) {
                if (null == user.getEmailFlag() || !user.getEmailFlag().equals(EmailStatusEnum.IS_ACTIVATION)) {
                    throw new MyUsernameNotFoundException("邮箱未激活！");
                }
            }
            userByUserName.setQqId(user.getQqId());
            userService.updateById(userByUserName);

            // 添加权限
            List<UserRole> userRoles = userRoleService.list(new QueryWrapper<UserRole>()
                    .eq("user_id", userByUserName.getId()));
            for (UserRole userRole : userRoles) {
                Role role = roleService.getById(userRole.getRoleId());
                authorities.add(new SimpleGrantedAuthority(role.getName().getRoleName()));
            }
            org.springframework.security.core.userdetails.User principal = new org.springframework.security.core.userdetails.User(
                    userByUserName.getUsername(), userByUserName.getPassword(), authorities);
            return new UsernamePasswordAuthenticationToken(principal, null, authorities);
        } else {
            if (null != userByUserName) {
                throw new NoBindingException("用户名被占用!");
            }
            if (null == user.getRealName() || "".equals(user.getRealName())) {
                throw new NoBindingException("真实姓名不能为空！");
            }
            Boolean autoRegister = settingService.getById(1).getIsRegister();
            if (autoRegister) {
                user.setRegister(RegisterEnum.REGISTER_YES);
            } else {
                user.setRegister(RegisterEnum.UN_REGISTER);
            }
            user.setPassword(encoder.encode(user.getPassword()));
            boolean save = userService.save(user);
            if (save) {
                userRoleService.saveOrUpdate(new UserRole().setUserId(user.getId()).setRoleId(1),
                        new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, user.getId()));

                List<UserRole> userRoles = userRoleService.list(new QueryWrapper<UserRole>()
                        .eq("user_id", user.getId()));
                for (UserRole userRole : userRoles) {
                    Role role = roleService.getById(userRole.getRoleId());
                    authorities.add(new SimpleGrantedAuthority(role.getName().getRoleName()));
                }
                org.springframework.security.core.userdetails.User principal = new org.springframework.security.core.userdetails.User(
                        user.getUsername(), user.getPassword(), authorities);
                return new UsernamePasswordAuthenticationToken(principal, null, authorities);
            } else {
                throw new NoBindingException("绑定失败！");
            }
        }
    }
}
